fix(init): generate root CLAUDE.md for --ai claude#1988
fix(init): generate root CLAUDE.md for --ai claude#1988arun-gupta wants to merge 8 commits intogithub:mainfrom
Conversation
Ensure `specify init --ai claude` creates a minimal root CLAUDE.md pointing to `.specify/memory/constitution.md`, and add a regression test for issue github#1983. Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Ensures specify init --ai claude creates a minimal root CLAUDE.md so Claude Code automatically picks up Spec Kit guidance by pointing to .specify/memory/constitution.md.
Changes:
- Added
ensure_claude_md()helper to generate a rootCLAUDE.mdfor Claude projects (preserving any existing file). - Wired Claude-specific
CLAUDE.mdgeneration into theinit()flow and step tracker. - Added an end-to-end CLI test asserting
CLAUDE.mdis created and contains expected guidance.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Adds ensure_claude_md() and calls it during init() for --ai claude. |
tests/test_ai_skills.py |
Adds a CLI test to verify CLAUDE.md is created during offline init. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
generate CLAUDE.md only when `.specify/memory/constitution.md` exists to avoid misleading guidance, and make the regression test deterministic by patching init scaffolding. Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@dhilipkumars Can you see if this still needs to be done? |
|
Claude code has now merged custom commands with skills as mentioned here
and when i initialize speck-kit for claude it automatically creates skills, do see any reason to still support legacy commands? and do this and skills work the exact same way as legacy slash commands you can invoke them with |
|
@dhilipkumars, this is not about Claude's commands. It's about generating a minimal |
|
i see what you mean i would rather recommend them as part of Pre-execution check in specify.md that will work for all the agents instead of may be we should do that for all the commands like what do you think ? @arun-gupta and @mnriem |
|
@dhilipkumars The Claude specific integration could deal with it. Note that the update-agent-context script actually does update those specific files |
|
@dhilipkumars where would this pre-execution checks be placed? In Here is what is working for me https://github.com/arun-gupta/repo-pulse/blob/main/CLAUDE.md |
@arun-gupta my suggestions was to bake this indirection in the command/skill directly for eg: here is the i think @mnriem is leaning towards having this logic in WDYT? |
|
What I meant is really 2 fold here. The Claude integration at specify init time can merge/create CLAUDE.md with whatever we think should be in there. Then later on it will be updated by update-agent-context as part of the regular flow |
gotcha thanks, okay then lets get this PR merged away @arun-gupta please address the co-pilot review comments/resolve conflicts. |
|
But as it currently stands it is NOT doing the work in the integration code and that needs to be changed |
@dhilipkumars I updated the PR a while back and now have resolved the conversation. Let me know if anything else is required. |
@arun-gupta id start with the following
|
|
It needs to be updated to use |
…1983 # Conflicts: # src/specify_cli/__init__.py # tests/test_ai_skills.py
Test results after merge resolutionThis PR has been rebased/merged against the latest New unit tests4 new tests in Coverage:
Full Claude integration suiteAll 23 tests pass: Full repo test suiteThe single failure ( |
There was a problem hiding this comment.
Pull request overview
Adds support for generating a root CLAUDE.md during Claude integration setup so Claude Code has a stable entrypoint that points to the project’s .specify/memory/constitution.md.
Changes:
- Add
ClaudeIntegration.ensure_claude_md()and call it fromClaudeIntegration.setup()to create and manifest-track a minimal rootCLAUDE.mdwhen the constitution exists. - Add integration tests covering creation, skipping when constitution is missing, and preserving an existing
CLAUDE.md. - Add a CLI-level integration test to verify
specify init --ai clauderesults inCLAUDE.mdbeing present.
Show a summary per file
| File | Description |
|---|---|
| src/specify_cli/integrations/claude/init.py | Creates CLAUDE.md during Claude setup (gated on constitution existence) and records it in the integration manifest. |
| tests/integrations/test_integration_claude.py | Adds tests to validate CLAUDE.md creation behavior in both integration setup and CLI init flows. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/claude/init.py:172
- The generated CLAUDE.md lists core SpecKit commands but omits
/speckit.constitution, which is part of the standard workflow (and is shown as a first next-step in init output). Consider adding it to the command list (or otherwise aligning the generated guidance with the supported slash commands).
"## SpecKit Commands\n"
"- `/speckit.specify` — generate spec\n"
"- `/speckit.plan` — generate plan\n"
"- `/speckit.tasks` — generate task list\n"
"- `/speckit.implement` — execute plan\n\n"
- Files reviewed: 2/2 changed files
- Comments generated: 2
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
noted. |
- Introduce CONSTITUTION_REL_PATH constant in specify_cli and reuse it in ensure_constitution_from_template and ClaudeIntegration.ensure_claude_md so the path cannot drift between init scaffolding and integration setup. - Make ensure_claude_md a classmethod that uses cls.context_file instead of hardcoding "CLAUDE.md". - Expand CLAUDE.md body to list all core speckit workflow commands (constitution, specify, clarify, plan, tasks, analyze, checklist, implement) so Claude Code sees the full workflow. - Strengthen tests to assert every section header and every command line via shared EXPECTED_CLAUDE_MD_SECTIONS / _COMMANDS constants. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR aims to ensure specify init --ai claude produces a minimal root CLAUDE.md that points Claude Code at the project’s constitution (.specify/memory/constitution.md), and adds regression tests for that behavior.
Changes:
- Add a shared
CONSTITUTION_REL_PATHconstant and use it when copying the constitution into.specify/memory/. - Implement
ClaudeIntegration.ensure_claude_md()and invoke it during Claude integration setup to generateCLAUDE.mdwhen appropriate. - Add integration tests asserting
CLAUDE.mdcreation/skipping/preservation and validating expected sections/commands.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/claude/__init__.py |
Adds ensure_claude_md() and appends CLAUDE.md to created files/manifest during Claude setup. |
src/specify_cli/__init__.py |
Introduces CONSTITUTION_REL_PATH and reuses it in ensure_constitution_from_template(). |
tests/integrations/test_integration_claude.py |
Adds coverage for CLAUDE.md generation behavior in both integration setup and CLI init. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/3 changed files
- Comments generated: 2
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. If not applicable, please explain why. Hopefully this is the last review needed. Thanks for working on this!
The previous placement called ensure_claude_md() from ClaudeIntegration.setup(), which runs BEFORE ensure_constitution_from_template() in the init() flow. Since the creation is gated on the constitution file existing, CLAUDE.md was silently skipped on a fresh `specify init --ai claude` — the exact scenario this PR is meant to fix. The previous tests masked this bug by pre-creating the constitution file before invoking setup() or the CLI, so they never exercised the real ordering. Fix: - Add a generic `ensure_context_file(project_root, manifest)` hook on IntegrationBase (default no-op) that runs after the constitution is in place. Integrations needing a root context file (e.g. CLAUDE.md) override it. - Move the CLAUDE.md creation from ClaudeIntegration.setup() into ClaudeIntegration.ensure_context_file(), which also records the file in the integration manifest. - Call resolved_integration.ensure_context_file(...) from init() immediately after ensure_constitution_from_template(...), and re-save the manifest if a file was created. Tests: - Rewrite the CLI end-to-end test to start from a truly empty project (no pre-created constitution) so it fails if the ordering regresses. It now asserts that BOTH the constitution and CLAUDE.md exist. - Add a test proving setup() alone does NOT create CLAUDE.md. - Update the three unit tests to call ensure_context_file directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a post-constitution initialization hook so the Claude integration can generate a minimal root CLAUDE.md that points Claude Code at the project’s authoritative constitution file (.specify/memory/constitution.md), addressing the missing-file behavior in specify init --ai claude.
Changes:
- Introduces an
IntegrationBase.ensure_context_file()hook (no-op by default) intended to run after constitution setup duringspecify init. - Implements
ClaudeIntegration.ensure_context_file()to createCLAUDE.mdwhen the constitution exists and noCLAUDE.mdis present. - Adds integration tests verifying creation/skip/preservation behaviors and an init-flow ordering check.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Defines a shared CONSTITUTION_REL_PATH and invokes the new post-constitution integration hook during init(). |
src/specify_cli/integrations/base.py |
Adds the new ensure_context_file() extension point to the integration base class. |
src/specify_cli/integrations/claude/__init__.py |
Implements Claude-specific creation of root CLAUDE.md and records it in the integration manifest. |
tests/integrations/test_integration_claude.py |
Adds unit + init-flow tests covering CLAUDE.md creation logic and ordering. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/claude/init.py:194
- For consistency with other manifest-tracked file writes, prefer using
IntegrationBase.write_file_and_record()to write+recordCLAUDE.md(it also normalizes newlines). Usingwrite_text()+record_file_in_manifest()bypasses that standard path.
)
context_file.write_text(content, encoding="utf-8")
self.record_file_in_manifest(context_file, project_root, manifest)
return context_file
- Files reviewed: 4/4 changed files
- Comments generated: 2
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Ensures specify init --ai claude generates a minimal root CLAUDE.md that points Claude Code at the authoritative constitution file, fixing the missing-context-file gap in the Claude init flow.
Changes:
- Add a shared
CONSTITUTION_REL_PATHconstant and use it for constitution scaffolding. - Introduce an
IntegrationBase.ensure_context_file()post-constitution hook and invoke it duringinit. - Implement the hook for the Claude integration and add integration tests asserting the correct behavior.
Show a summary per file
| File | Description |
|---|---|
| tests/integrations/test_integration_claude.py | Adds unit + end-to-end coverage for creating/preserving CLAUDE.md based on constitution presence. |
| src/specify_cli/integrations/claude/init.py | Implements ensure_context_file() to generate minimal CLAUDE.md when constitution exists. |
| src/specify_cli/integrations/base.py | Adds the ensure_context_file() hook to the integration base API (default no-op). |
| src/specify_cli/init.py | Centralizes constitution path via CONSTITUTION_REL_PATH and calls the new hook after constitution setup in init(). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 2
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback, if not applicable please explain why
…ests Addresses two review comments: - ensure_context_file now uses the base class's write_file_and_record() helper instead of Path.write_text + a separate record_file_in_manifest call. This matches the pattern used everywhere else in integrations, normalizes \r\n -> \n to avoid platform newline translation, and keeps the write+manifest update consistent. - Tests now import and use CONSTITUTION_REL_PATH instead of hardcoding ".specify/memory/constitution.md", so the path stays in sync with the production constant. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Ensure
specify init --ai claudecreates a minimal rootCLAUDE.mdpointing to.specify/memory/constitution.mdMade-with: Cursor
Description
Fixes #1983
Testing
Ran the tests on my machine.
uv run specify --helpuv sync && uv run pytestHere is the output:
Here is the output
AI Disclosure
I used Cursor to understand the codebase and generate the code for this particular fix. I read through the code 3x to ensure it's aligned with the rest of the codebase. I own the responsibility for this fix.